home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / 3dlib15.zip / CTM3D.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-27  |  38KB  |  761 lines

  1. (******************************************************************************
  2. *                                    Ctm3d                                    *
  3. ******************************************************************************)
  4. Unit Ctm3d;
  5.  
  6. (*******************************************************************************
  7. *                          Homogeneous Coordinates                            *
  8. *                          -----------------------                            *
  9. *                                                                             *
  10. *      Homogeneous coordinates allow transformations to be represented by     *
  11. *      matrices. A 3x3 matrix is used for 2D transformations, and a 4x4 matrix*
  12. *      for 3D transformations.                                                *
  13. *                                                                             *
  14. *      THIS MODULE IMPLEMENTS ONLY 3D TRANSFORMATIONS.                        *
  15. *                                                                             *
  16. *      in homogeneous coordination the point P(x,y,z) is represented as       *
  17. *      P(w*x, w*y, w*z, w) for any scale factor w!=0.                         *
  18. *      in this module w == 1.                                                 *
  19. *                                                                             *
  20. * Transformations:                                                            *
  21. *          1. translation                                                     *
  22. *                  [x, y, z] --> [x + Dx, y + Dy, z + Dz]                     *
  23. *                                                                             *
  24. *                              ┌          ┐                                   *
  25. *                              │1  0  0  0│                                   *
  26. *              T(Dx, Dy, Dz) = │0  1  0  0│                                   *
  27. *                              │0  0  1  0│                                   *
  28. *                              │Dx Dy Dz 1│                                   *
  29. *                              └          ┘                                   *
  30. *          2. scaling                                                         *
  31. *                  [x, y, z] --> [Sx * x, Sy * y, Sz * z]                     *
  32. *                                                                             *
  33. *                          ┌          ┐                                       *
  34. *                          │Sx 0  0  0│                                       *
  35. *              S(Sx, Sy) = │0  Sy 0  0│                                       *
  36. *                          │0  0  Sz 0│                                       *
  37. *                          │0  0  0  1│                                       *
  38. *                          └          ┘                                       *
  39. *                                                                             *
  40. *          3. rotation                                                        *
  41. *                                                                             *
  42. *              a) Around the Z axis:                                          *
  43. *                                                                             *
  44. *                  [x, y, z] --> [x*cost - t*sint, x*sint + y*cost, z]        *
  45. *                      ┌                  ┐                                   *
  46. *                      │cost  sint   0   0│                                   *
  47. *              Rz(t) = │-sint cost   0   0│                                   *
  48. *                      │0     0      1   0│                                   *
  49. *                      │0     0      0   1│                                   *
  50. *                      └                  ┘                                   *
  51. *                                                                             *
  52. *              b) Around the X axis:                                          *
  53. *                                                                             *
  54. *                  [x, y, z] --> [x, y*cost - z*sint, y*sint + z*cost]        *
  55. *                      ┌                  ┐                                   *
  56. *                      │1     0     0    0│                                   *
  57. *              Rx(t) = │0     cost  sint 0│                                   *
  58. *                      │0    -sint  cost 0│                                   *
  59. *                      │0     0     0    1│                                   *
  60. *                      └                  ┘                                   *
  61. *                                                                             *
  62. *              c) Around the Y axis:                                          *
  63. *                                                                             *
  64. *                  [x, y, z] --> [xcost + z*sint, y, z*cost - x*sint]         *
  65. *                      ┌                  ┐                                   *
  66. *                      │cost  0   -sint  0│                                   *
  67. *              Ry(t) = │0     1    0     0│                                   *
  68. *                      │sint  0    cost  0│                                   *
  69. *                      │0     0    0     1│                                   *
  70. *                      └                  ┘                                   *
  71. *                                                                             *
  72. *   transformation of the vector [x,y,z,1] by transformation matrix T is given *
  73. *   by the formula:                                                           *
  74. *                                         ┌   ┐                               *
  75. *              [x', y', z', 1] = [x,y,z,1]│ T │                               *
  76. *                                         └   ┘                               *
  77. * Optimizations:                                                              *
  78. *   The most general composition of R, S and T operations will produce a matrix*
  79. *   of the form:                                                              *
  80. *              ┌                       ┐                                      *
  81. *              │r11    r12     r13    0│                                      *
  82. *              │r21    r22     r23    0│                                      *
  83. *              │r31    r32     r33    0│                                      *
  84. *              │tx     ty      tz     1│                                      *
  85. *              └                       ┘                                      *
  86. *   The task of matrix multiplication can be simplified by                    *
  87. *      x' = x*r11 + y*r21 + z*r31 + tx                                        *
  88. *      y' = x*r12 + y*r22 + z*r32 + ty                                        *
  89. *      z' = x*r13 + y*r23 + z*r33 + tz                                        *
  90. *                                                                             *
  91. *                                                                             *
  92. * See also:                                                                   *
  93. *      "Fundamentals of Interactive Computer Graphics" J.D FOLEY A.VAN DAM    *
  94. *      Adison-Weslely ISBN 0-201-14468-9 pp 245-265                           *
  95. *******************************************************************************)
  96.  
  97. interface
  98.  
  99. uses 
  100.    hdr3d
  101.    ;
  102.  
  103. type
  104.     ctmPtr = ^ ctm;         
  105.     ctm = object
  106.        r11, r12, r13   : real; { change to single if numeric processor is present }
  107.        r21, r22, r23   : real;
  108.        r31, r32, r33   : real;
  109.        tx,  ty,  tz    : real;
  110.  
  111.        constructor SetUnit; { set to the unit (I) matrix }
  112.        constructor Copy(var src : ctm); { construct from another }
  113.        procedure save(var dest : ctm);
  114.  
  115.        procedure translate(Dx, Dy, Dz : real); { used to move .. }
  116.  
  117.        procedure translateX(dx : real);
  118.        procedure translateY(dy : real);
  119.        procedure translateZ(dz : real); { translate in one axis only }
  120.        {use these routines for single axis translations, they are faster!}
  121.  
  122.        procedure rotateX(t : real);
  123.        procedure rotateY(t : real);
  124.        procedure rotateZ(t : real);
  125.  
  126.        procedure scale(Sx, Sy, Sz : real);
  127.  
  128.        procedure scaleX(sx : real);
  129.        procedure scaleY(sy : real);
  130.        procedure scaleZ(sz : real);
  131.        {use these routines for single axis scaling, they are faster!!!}
  132.  
  133.        procedure Left_translate(Dx, Dy, Dz : real);
  134.  
  135.        procedure Left_translateX(dx : real);
  136.        procedure Left_translateY(dy : real);
  137.        procedure Left_translateZ(dz : real);
  138.        {use these Left_ routines for single axis translations, they are faster!}
  139.  
  140.        procedure Left_rotateX(t : real);
  141.        procedure Left_rotateY(t : real);
  142.        procedure Left_rotateZ(t : real);
  143.  
  144.        procedure Left_scale(Sx, Sy, Sz : real);
  145.  
  146.        procedure Left_scaleX(sx : real);
  147.        procedure Left_scaleY(sy : real);
  148.        procedure Left_scaleZ(sz : real);
  149.        {use these routines for single axis scaling, they are faster!!!}
  150.  
  151.        procedure transform(var t: point3d; p : point3d);
  152.        {
  153.          Note that t (target) is var, but p is NOT.
  154.          p cannot be a var parameter, because if the same point is
  155.          transformed, data should be copied for correct results
  156.        }
  157.        procedure inv_transform(var p : point3d);
  158.        { inv_transform changes the input point }
  159.  
  160.        procedure inverse; { M ^-1 .Bring the matrix to (-1) power}
  161.        procedure multiply(var c : ctm); {multiply from right self * c}
  162.        procedure Multiply_2(var a, b : ctm);
  163.     end;
  164.  
  165. implementation
  166.  
  167. const 
  168.    pi = 3.1415926535897932385;
  169.  
  170. (******************************************************************************
  171. *                                 ctm.SetUnit                                 *
  172. * ctm.SetUnit -- set the ctm to the unit matrix.                              *
  173. ******************************************************************************)
  174. constructor ctm.SetUnit;
  175. begin
  176.     r11 := 1; r12 := 0; r13 := 0;
  177.     r21 := 0; r22 := 1; r23 := 0;
  178.     r31 := 0; r32 := 0; r33 := 1;
  179.     Tx  := 0; Ty  := 0; Tz  := 0;
  180. end; {ctm.setUnit}
  181.  
  182. (******************************************************************************
  183. *                                  ctm.copy                                   *
  184. * Copy another CTM to SELF.                                                   *
  185. * This copy is done this way because TP does not construct SELF if we perform *
  186. *  Self := SRC;                                                               *
  187. ******************************************************************************)
  188. constructor ctm.copy;
  189. begin                      
  190.     r11 := Src.r11;
  191.     r12 := Src.r12;
  192.     r13 := Src.r13;
  193.     r21 := Src.r21;
  194.     r22 := Src.r22;
  195.     r23 := Src.r23;
  196.     r31 := Src.r31;
  197.     r32 := Src.r32;
  198.     r33 := Src.r33;
  199.     tx := Src.tx;
  200.     ty := Src.ty;
  201.     tz := Src.tz;
  202. end; {ctm.copy}
  203.  
  204. (*******************************************************************************
  205. *                                  ctm.save                                    *
  206. * Save CTM in specified variable CTM                                           *
  207. *******************************************************************************)
  208. procedure ctm.save;
  209. begin
  210.     dest := self;
  211. end; {ctm.self}
  212.  
  213. (******************************************************************************
  214. *                                ctm.translate                                *
  215. * ctm.translate -- multyply ctm by T(dx,dy,dz). ctm = ctm * T(dx,dy,dz)       *
  216. *     ┌                       ┐    ┌             ┐    ┌                   ┐   *
  217. *     │r11    r12     r13    0│    │1  0   0   0 │    │r11   r12   r31   0│   *
  218. *     │r21    r22     r23    0│ *  │0  1   0   0 │ =  │r21   r22   r31   0│   *
  219. *     │r31    r32     r33    0│    │0  0   1   0 │    │r21   r22   r31   0│   *
  220. *     │tx     ty      tz     1│    │Dx  Dy  Dz  1│    │tx'   ty'   tz'   1│   *
  221. *     └                       ┘    └             ┘    └                   ┘   *
  222. *                                                                             *
  223. *    tx' = tx + Dx                                                            *
  224. *    ty' = ty + Dy                                                            *
  225. *    tz' = tz + Dz                                                            *
  226. ******************************************************************************)
  227. procedure ctm.translate;
  228. begin
  229.     Tx := Tx + Dx;
  230.     Ty := Ty + Dy;
  231.     Tz := Tz + Dz;
  232. end; {ctm.translate}
  233.  
  234. (******************************************************************************
  235. *                             ctm.Left_translate                              *
  236. * ctm.Left_translate  --  multyply ctm by T(dx,dy,dz) on the left.            *
  237. *                         ctm = T(dx,dy,dz) * ctm                             *
  238. *      ┌             ┐ ┌                       ┐     ┌                   ┐    *
  239. *      │1   0   0   0│ │r11    r12     r13    0│     │r11   r12   r31   0│    *
  240. *      │0   1   0   0│ │r21    r22     r23    0│  =  │r21   r22   r31   0│    *
  241. *      │0   0   1   0│ │r31    r32     r33    0│     │r21   r22   r31   0│    *
  242. *      │Dx  Dy  Dz  1│ │tx     ty      tz     1│     │tx'   ty'   tz'   1│    *
  243. *      └             ┘ └                       ┘     └                   ┘    *
  244. *                                                                             *
  245. *    tx' = r11 * Dx + r21 * Dy + r31 * Dz + tx                                *
  246. *    ty' = r12 * Dx + r22 * Dy + r32 * Dz + ty                                *
  247. *    tz' = r13 * Dx + r23 * Dy + r33 * Dz + tz                                *
  248. ******************************************************************************)
  249. procedure ctm.Left_translate;
  250. begin
  251.     Tx := Tx + r11 * Dx + r21 * Dy + r31 * Dz;
  252.     Ty := Ty + r12 * Dx + r22 * Dy + r32 * Dz;
  253.     Tz := Tz + r13 * Dx + r23 * Dy + r33 * Dz;
  254. end; {ctm.Left_translate}
  255.  
  256. (*******************************************************************************
  257. *                               ctm.translateX                                 *
  258. * Notice - This procedure is FASTER then translate(dx, 0, 0)                   *
  259. *******************************************************************************)
  260. procedure ctm.translateX;
  261. begin
  262.        tx := tx+dx;
  263. end; {ctm.translateX}
  264.  
  265. (*******************************************************************************
  266. *                            ctm.Left_translateX                               *
  267. *******************************************************************************)
  268. procedure ctm.Left_translateX;
  269. begin
  270.     tx := tx + dx * r11;
  271.     ty := ty + dx * r12;
  272.     tz := tz + dx * r13;
  273. end; {ctm.left_translateX}
  274.  
  275. (*******************************************************************************
  276. *                               ctm.translateY                                 *
  277. *******************************************************************************)
  278. procedure ctm.translateY;
  279. begin
  280.     ty := ty+dy;
  281. end; {ctm.translateY}
  282.  
  283. (*******************************************************************************
  284. *                            ctm.Left_translateY                               *
  285. *******************************************************************************)
  286. procedure ctm.Left_translateY;
  287. begin
  288.        tx := tx + dy * r21;
  289.        ty := ty + dy * r22;
  290.        tz := tz + dy * r23;
  291. end; {ctm.Left_translateY}
  292.  
  293.  
  294. (*******************************************************************************
  295. *                               ctm.translateZ                                 *
  296. *******************************************************************************)
  297. procedure ctm.translateZ;
  298. begin
  299.        tz := tz+dz;
  300. end; {ctm.translateZ}
  301.  
  302. (*******************************************************************************
  303. *                            ctm.Left_translateZ                               *
  304. *******************************************************************************)
  305. procedure ctm.Left_translateZ;
  306. begin
  307.        tx := tx + dz * r31;
  308.        ty := ty + dz * r32;
  309.        tz := tz + dz * r33;
  310. end; {ctm.Left_translateZ}
  311.  
  312. (*     the above 6 procedures are used for single axis translation - # of FP
  313.        operations is 1/3, # of arguments passed is 1/3, try using these
  314.        procedures when possiable to improve animation *)
  315.  
  316. (******************************************************************************
  317. *                                  ctm.scale                                  *
  318. * ctm.scale -- multyply ctm by S(sx,sy,sz). ctm = ctm * S(sx,sy,sz)           *
  319. *   ┌                   ┐   ┌             ┐   ┌                            ┐  *
  320. *   │r11   r12    r13  0│   │Sx  0   0   0│   │Sx*r11   Sy*r12   Sz*r13   0│  *
  321. *   │r21   r22    r23  0│ * │0   Sy  0   0│ = │Sx*r21   Sy*r22   Sz*r13   0│  *
  322. *   │r31   r32    r33  0│   │0   0   Sz  0│   │Sx*r31   Sy*r32   Sz*r33   0│  *
  323. *   │tx    ty    tz    1│   │0   0   0   1│   │Sx*tx    Sy*ty    Sz*tz    1│  *
  324. *   └                   ┘   └             ┘   └                            ┘  *
  325. ******************************************************************************)
  326. procedure ctm.scale;
  327. begin
  328.     r11 := r11*Sx;     r12 := r12*Sy;      r13 := r13*Sz;
  329.     r21 := r21*Sx;     r22 := r22*Sy;      r23 := r23*Sz;
  330.     r31 := r31*Sx;     r32 := r32*Sy;      r33 := r33*Sz;
  331.     tx :=  tx*Sx;      ty  :=  ty*Sy;      tz  :=  tz*Sz
  332. end; {ctm.scale}
  333.  
  334. (******************************************************************************
  335. *                               ctm.Left_scale                                *
  336. * ctm.Left_scale   -- multyply ctm by S(sx,sy,sz) on the left.                *
  337. *                     ctm = S(sx,sy,sz) * ctm                                 *
  338. *   ┌             ┐   ┌                    ┐   ┌                            ┐ *
  339. *   │Sx  0   0   0│   │r11   r12    r13   0│   │Sx*r11   Sy*r12   Sz*r13   0│ *
  340. *   │0   Sy  0   0│ * │r21   r22    r23   0│ = │Sx*r21   Sy*r22   Sz*r13   0│ *
  341. *   │0   0   Sz  0│   │r31   r32    r33   0│   │Sx*r31   Sy*r32   Sz*r33   0│ *
  342. *   │0   0   0   1│   │tx    ty     tz    1│   │   tx       ty       tz    1│ *
  343. *   └             ┘   └                    ┘   └                            ┘ *
  344. ******************************************************************************)
  345. procedure ctm.Left_scale;
  346. begin
  347.     r11 := r11*Sx;     r12 := r12*Sy;      r13 := r13*Sz;
  348.     r21 := r21*Sx;     r22 := r22*Sy;      r23 := r23*Sz;
  349.     r31 := r31*Sx;     r32 := r32*Sy;      r33 := r33*Sz;
  350. end; {ctm.left_scale}
  351.  
  352. (*******************************************************************************
  353. *                                 ctm.scaleZ                                   *
  354. *******************************************************************************)
  355. procedure ctm.scaleZ;
  356. begin
  357.     r13 := r13*Sz;
  358.     r23 := r23*Sz;
  359.     r33 := r33*Sz;
  360.     tz :=  tz*Sz;
  361. end; {ctm.scaleZ}
  362.  
  363. (*******************************************************************************
  364. *                              ctm.Left_scaleZ                                 *
  365. *******************************************************************************)
  366. procedure ctm.Left_scaleZ;
  367. begin
  368.     r31 := r31*Sz;
  369.     r32 := r32*Sz;
  370.     r33 := r33*Sz;
  371. end; {ctm.left_scaleZ}
  372.  
  373. (*******************************************************************************
  374. *                                 ctm.scaleY                                   *
  375. *******************************************************************************)
  376. procedure ctm.scaleY;
  377. begin
  378.        r12 := r12*Sy;
  379.        r22 := r22*Sy;
  380.        r32 := r32*Sy;
  381.        ty  :=  ty*Sy;
  382. end; {ctm.scaleY}
  383.  
  384. (*******************************************************************************
  385. *                              ctm.Left_scaleY                                 *
  386. *******************************************************************************)
  387. procedure ctm.Left_scaleY;
  388. begin
  389.     r21 := r21*Sy;
  390.     r22 := r22*Sy;
  391.     r23 := r23*Sy;
  392. end; {ctm.Left_scaleY}
  393.  
  394. (*******************************************************************************
  395. *                                 ctm.scaleX                                   *
  396. *******************************************************************************)
  397. procedure ctm.scaleX;
  398. begin
  399.     r11 := r11*Sx;
  400.     r21 := r21*Sx;
  401.     r31 := r31*Sx;
  402.     tx :=  tx*Sx;
  403. end; {ctm.scaleX}
  404.  
  405. (*******************************************************************************
  406. *                              ctm.Left_scaleX                                 *
  407. *******************************************************************************)
  408. procedure ctm.Left_scaleX;
  409. begin
  410.     r11 := r11*Sx;
  411.     r12 := r12*Sx;
  412.     r13 := r13*Sx;
  413. end; {ctm.Left_scaleX}
  414.  
  415. (* the above 6 routines should be used for single axis scale, they are much
  416.        faster then calling the general scale routine (with a factor of
  417.        better then 3), and require less arguments *)
  418.  
  419. (******************************************************************************
  420. *                                 ctm.rotateZ                                 *
  421. * ctm.rotateZ -- multyply ctm by Rz(t). ctm = ctm * Rz(t)                     *
  422. *   ┌                   ┐   ┌                  ┐   ┌                    ┐     *
  423. *   │r11   r12    r13  0│   │cost  sint   0   0│   │r11'  r12'   r13   0│     *
  424. *   │r21   r22    r23  0│   │-sint cost   0   0│   │r21'  r22'   r23   0│     *
  425. *   │r31   r32    r33  0│ * │0     0      1   0│ = │r31'  r32'   r33   0│     *
  426. *   │tx    ty    tz    1│   │0     0      0   1│   │tx'   ty'    tz    1│     *
  427. *   └                   ┘   └                  ┘   └                    ┘     *
  428. *                                                                             *
  429. *   r11' = r11*cost - r12*sint                                                *
  430. *   r21' = r21*cost - r22*sint                                                *
  431. *   r31' = r31*cost - r32*sint                                                *
  432. *   tx'  = tx *cost - ty *sint                                                *
  433. *   r12' = r11*sint + r12*cost                                                *
  434. *   r22' = r21*sint + r22*cost                                                *
  435. *   r32' = r31*sint + r32*cost                                                *
  436. *   ty'  = tx *sint + ty *cost                                                *
  437. *                                                                             *
  438. ******************************************************************************)
  439. procedure ctm.rotateZ;
  440. var
  441.     cost, sint : real;
  442.     tmp        : real;
  443. begin
  444.     cost := cos(t / 180.0 * pi);
  445.     sint := sin(t / 180.0 * pi);
  446.  
  447.     tmp := r11*cost - r12*sint;
  448.     r12 := r11*sint + r12*cost;
  449.     r11 := tmp;
  450.     tmp := r21*cost - r22*sint;
  451.     r22 := r21*sint + r22*cost;
  452.     r21 := tmp;
  453.     tmp := r31*cost - r32*sint;
  454.     r32 := r31*sint + r32*cost;
  455.     r31 := tmp;
  456.     tmp := tx *cost - ty *sint;
  457.     ty := tx *sint + ty *cost;
  458.     tx := tmp;
  459. end; {ctm.rotateZ}
  460.  
  461. (******************************************************************************
  462. *                              ctm.Left_rotateZ                               *
  463. * ctm.Left_rotateZ  -- multyply ctm by Rz(t) on the left. ctm = Rz(t) * ctm   *
  464. *  ┌                 ┐   ┌                    ┐   ┌                    ┐      *
  465. *  │cost  sint   0   0│   │r11   r12   r13   0│   │r11'  r12'   r13'  0│      *
  466. *  │-sint cost   0   0│   │r21   r22   r23   0│   │r21'  r22'   r23'  0│      *
  467. *  │0    0      1   0│ * │r31   r32    r33   0│ = │r31   r32    r33   0│      *
  468. *  │0    0      0   1│   │tx    ty     tz    1│   │tx    ty     tz    1│      *
  469. *  └                 ┘   └                    ┘   └                    ┘      *
  470. *                                                                             *
  471. *   r11' = r11*cost + r21*sint                                                *
  472. *   r12' = r12*cost + r22*sint                                                *
  473. *   r13' = r13*cost + r23*sint                                                *
  474. *   r21' = r21*cost - r11*sint                                                *
  475. *   r22' = r22*cost - r12*sint                                                *
  476. *   r23' = r23*cost - r13*sint                                                *
  477. *                                                                             *
  478. ******************************************************************************)
  479. procedure ctm.Left_rotateZ;
  480. var
  481.     cost, sint : real;
  482.     tmp        : real;
  483. begin
  484.      cost := cos(t / 180.0 * pi);
  485.      sint := sin(t / 180.0 * pi);
  486.  
  487.     tmp := r11 * cost + r21 * sint;
  488.     r21 := r21 * cost - r11 * sint;
  489.     r11 := tmp;
  490.     tmp := r12 * cost + r22 * sint;
  491.     r22 := r22 * cost - r12 * sint;
  492.     r12 := tmp;
  493.     tmp := r13 * cost + r23 * sint;
  494.     r23 := r23 * cost - r13 * sint;
  495.     r13 := tmp;
  496. end; {ctm.Left_rotateZ}
  497.  
  498. (******************************************************************************
  499. *                                 ctm.rotateX                                 *
  500. * ctm.rotateX -- multyply ctm by Rx(t). ctm = ctm * Rx(t)                     *
  501. *   ┌                   ┐   ┌                  ┐   ┌                    ┐     *
  502. *   │r11   r12    r13  0│   │1     0     0    0│   │r11   r12'   r13'  0│     *
  503. *   │r21   r22    r23  0│   │0     cost  sint 0│   │r21   r22'   r23'  0│     *
  504. *   │r31   r32    r33  0│ * │0    -sint  cost 0│ = │r31   r32'   r33'  0│     *
  505. *   │tx    ty    tz    1│   │0     0     0    1│   │tx    ty'    tz'   1│     *
  506. *   └                   ┘   └                  ┘   └                    ┘     *
  507. *                                                                             *
  508. *   r12' = r12*cost - r13*sint                                                *
  509. *   r13' = r12*sint + r13*cost                                                *
  510. *   r22' = r22*cost - r23*sint                                                *
  511. *   r23' = r22*sint + r23*cost                                                *
  512. *   ty'  = ty *cost - tz *sint                                                *
  513. *   tz'  = ty *sint + tz *cost                                                *
  514. ******************************************************************************)
  515. procedure ctm.rotateX;
  516. var
  517.     cost, sint : real;
  518.     tmp        : real;
  519. begin
  520.      cost := cos(t / 180.0 * pi); {constants are evaluated at compile time}
  521.      sint := sin(t / 180.0 * pi);
  522.  
  523.     tmp := r12*cost - r13*sint;
  524.     r13 := r12*sint + r13*cost;
  525.     r12 := tmp;
  526.     tmp := r22*cost - r23*sint;
  527.     r23 := r22*sint + r23*cost;
  528.     r22 := tmp;
  529.     tmp := r32*cost - r33*sint;
  530.     r33 := r32*sint + r33*cost;
  531.     r32 := tmp;
  532.     tmp := ty *cost - tz *sint;
  533.     tz := ty *sint + tz *cost;
  534.     ty := tmp;
  535. end; {ctm.rotateX}
  536.  
  537. (******************************************************************************
  538. *                              ctm.Left_rotateX                               *
  539. * ctm.Left_rotateX  -- multyply ctm by Rx(t) on the left. ctm = Rx(t) * ctm   *
  540. *  ┌                 ┐   ┌                    ┐   ┌                    ┐      *
  541. *  │1    0     0    0│   │r11   r12    r13   0│   │r11   r12    r13   0│      *
  542. *  │0    cost  sint 0│   │r21   r22    r23   0│   │r21'  r22'   r23'  0│      *
  543. *  │0   -sint  cost 0│ * │r31   r32    r33   0│ = │r31'  r32'   r33'  0│      *
  544. *  │0    0     0    1│   │tx    ty     tz    1│   │tx    ty     tz    1│      *
  545. *  └                 ┘   └                    ┘   └                    ┘      *
  546. *                                                                             *
  547. *   r21' = r21*cost + r31*sint                                                *
  548. *   r22' = r22*cost + r32*sint                                                *
  549. *   r23' = r23*cost + r33*sint                                                *
  550. *   r31' = r31*cost - r21*sint                                                *
  551. *   r32' = r32*cost - r22*sint                                                *
  552. *   r33' = r33*cost - r23*sint                                                *
  553. *                                                                             *
  554. ******************************************************************************)
  555. procedure ctm.Left_rotateX;
  556. var
  557.     cost, sint : real;
  558.     tmp        : real;
  559. begin
  560.      cost := cos(t / 180.0 * pi);
  561.      sint := sin(t / 180.0 * pi);
  562.  
  563.     tmp := r21 * cost + r31 * sint;
  564.     r31 := r31 * cost - r21 * sint;
  565.     r21 := tmp;
  566.     tmp := r22 * cost + r32 * sint;
  567.     r32 := r32 * cost - r22 * sint;
  568.     r22 := tmp;
  569.     tmp := r23 * cost + r33 * sint;
  570.     r33 := r33 * cost - r23 * sint;
  571.     r23 := tmp;
  572. end; {ctm.Left_rotateX}
  573.  
  574. (******************************************************************************
  575. *                                 ctm.rotateY                                 *
  576. * ctm.rotateY -- multyply ctm by Rx(t). ctm = ctm * Ry(t)                     *
  577. *   ┌                   ┐   ┌                  ┐   ┌                    ┐     *
  578. *   │r11   r12    r13  0│   │cost  0   -sint  0│   │r11'  r12    r13'  0│     *
  579. *   │r21   r22    r23  0│   │0     1    0     0│   │r21'  r22    r23'  0│     *
  580. *   │r31   r32    r33  0│ * │sint  0    cost  0│ = │r31'  r32    r33'  0│     *
  581. *   │tx    ty    tz    1│   │0     0    0     1│   │tx    ty'    tz'   1│     *
  582. *   └                   ┘   └                  ┘   └                    ┘     *
  583. *                                                                             *
  584. *   r11' = r11*cost + r13*sint                                                *
  585. *   r13' = r13*cost - r11*sint                                                *
  586. *   r21' = r21*cost + r23*sint                                                *
  587. *   r23' = r23*cost - r21*sint                                                *
  588. *   tx'  = tx *cost + tz *sint                                                *
  589. *   tz'  = tz *cost - tx *sint                                                *
  590. ******************************************************************************)
  591. procedure ctm.rotateY;
  592. var
  593.     cost, sint : real;
  594.     tmp        : real;
  595. begin
  596.      cost := cos(t / 180.0 * pi);
  597.      sint := sin(t / 180.0 * pi);
  598.  
  599.     tmp := r11*cost + r13*sint;
  600.     r13 := r13*cost - r11*sint;
  601.     r11 := tmp;
  602.     tmp := r21*cost + r23*sint;
  603.     r23 := r23*cost - r21*sint;
  604.     r21 := tmp;
  605.     tmp := r31*cost + r33*sint;
  606.     r33 := r33*cost - r31*sint;
  607.     r31 := tmp;
  608.     tmp := tx *cost + tz *sint;
  609.     tz := tz *cost - tx *sint;
  610.     tx := tmp;
  611. end; {ctm.rotateY}
  612.  
  613. (******************************************************************************
  614. *                              ctm.Left_rotateY                               *
  615. * ctm.Left_rotateY  -- multyply ctm by Ry(t) on the left. ctm = Ry(t) * ctm   *
  616. *  ┌                 ┐   ┌                    ┐   ┌                    ┐      *
  617. *  │cost  0   -sint 0│   │r11   r12   r13   0 │   │r11'  r12'   r13'  0│      *
  618. *  │0    1    0     0│   │r21   r22    r23   0│   │r21   r22    r23   0│      *
  619. *  │sint  0   cost  0│ * │r31   r32    r33   0│ = │r31'  r32'   r33'  0│      *
  620. *  │0    0    0     1│   │tx    ty     tz    1│   │tx    ty     tz    1│      *
  621. *  └                 ┘   └                    ┘   └                    ┘      *
  622. *                                                                             *
  623. *   r11' = r11*cost - r31*sint                                                *
  624. *   r12' = r11*cost - r32*sint                                                *
  625. *   r13' = r11*cost - r33*sint                                                *
  626. *   r31' = r31*cost + r11*sint                                                *
  627. *   r32' = r32*cost + r12*sint                                                *
  628. *   r33' = r33*cost + r13*sint                                                *
  629. *                                                                             *
  630. ******************************************************************************)
  631. procedure ctm.Left_rotateY;
  632. var
  633.     cost, sint : real;
  634.     tmp        : real;
  635. begin
  636.      cost := cos(t / 180.0 * pi);
  637.      sint := sin(t / 180.0 * pi);
  638.  
  639.     tmp := r11 * cost - r31 * sint;
  640.     r31 := r31 * cost + r11 * sint;
  641.     r11 := tmp;
  642.     tmp := r11 * cost - r32 * sint;
  643.     r32 := r32 * cost + r12 * sint;
  644.     r12 := tmp;
  645.     tmp := r11 * cost - r33 * sint;
  646.     r33 := r33 * cost + r13 * sint;
  647.     r13 := tmp;
  648. end; {ctm.Left_rotateY}
  649.  
  650. (******************************************************************************
  651. *                                ctm.transform                                *
  652. *  ctm.transform   -- transform [x,y,z] by the CTM.                           *
  653. *                                                                             *
  654. *  See remarks at the top.                                                    *
  655. ******************************************************************************)
  656. procedure ctm.transform;
  657. begin
  658.     t.x := p.x*r11 + p.y*r21 + p.z*r31 + tx;
  659.     t.y := p.x*r12 + p.y*r22 + p.z*r32 + ty;
  660.     t.z := p.x*r13 + p.y*r23 + p.z*r33 + tz;
  661. end; {ctm.transform}
  662.  
  663. (******************************************************************************
  664. *                              ctm.inv_transform                              *
  665. *  ctm.inv_transform -- transform [x',y',z'] by the INVERS                    *
  666. *                      transfomation CTM^-1                                   *
  667. *                                                                             *
  668. *  The inverse transformation is calculated by solving the 3 equations        *
  669. *     for x,y,z.                                                              *
  670. *                                                                             *
  671. *      x' = x*r11 + y*r21 + z*r31 + tx                                        *
  672. *      y' = x*r12 + y*r22 + z*r32 + ty                                        *
  673. *      z' = x*r13 + y*r23 + z*r33 + tz                                        *
  674. *                                                                             *
  675. ******************************************************************************)
  676. procedure ctm.inv_transform;
  677. var
  678.     d      : real;     { Delta }
  679.     d_x     : real;    { Delta X [X = Delta X / Delta] }
  680.     d_y     : real;    { Delta Y [Y = Delta Y / Delta] }
  681.     d_z     : real;    { Delta Z [Z = Delta Z / Delta] }
  682. begin
  683.     d :=  r11*(r22*r33 - r32*r23)
  684.         -r21*(r12*r33 - r13*r32)
  685.         +r31*(r12*r23 - r22*r13);
  686.     d_x:=  (p.x - tx)*(r22*r33 - r32*r23)
  687.          -r21*((p.y - ty)*r33 - (p.z - tz)*r32)
  688.          +r31*((p.y - ty)*r23 - r22*(p.z - tz));
  689.     d_y:=  r11*((p.y - ty)*r33 - r32*(p.z - tz))
  690.          -(p.x - tx)*(r12*r33 - r13*r32)
  691.          +r31*(r12*(p.z - tz) - (p.y - ty)*r13);
  692.     d_z:=  r11*(r22*(p.z - tz) - (p.y - ty)*r23)
  693.          -r21*(r12*(p.z - tz) - r13*(p.y - ty))
  694.          +(p.x - tx)*(r12*r23 - r22*r13);
  695.     p.x := round(d_x / d);
  696.     p.y := round(d_y / d);
  697.     p.z := round(d_z / d);
  698. end; {ctm.inv_transform}
  699.  
  700. (*******************************************************************************
  701. *                                ctm.multiply                                  *
  702. * here we multiply our ctm with another from the right : self * c -> self      *
  703. *******************************************************************************)
  704. procedure ctm.multiply;
  705. var
  706.     t : ctm;
  707. begin
  708.        t.r11 := r11*c.r11+r12*c.r21+r13*c.r31;
  709.        t.r21 := r21*c.r11+r22*c.r21+r23*c.r31;
  710.        t.r31 := r31*c.r11+r32*c.r21+r33*c.r31;
  711.        t.tx  := tx *c.r11+ty *c.r21+tz *c.r31+c.tx;
  712.  
  713.        t.r12 := r11*c.r12+r12*c.r22+r13*c.r32;
  714.        t.r22 := r21*c.r12+r22*c.r22+r23*c.r32;
  715.        t.r32 := r31*c.r12+r32*c.r22+r33*c.r32;
  716.        t.ty  := tx *c.r12+ty *c.r22+tz *c.r32+c.ty;
  717.  
  718.        t.r13 := r11*c.r13+r12*c.r23+r13*c.r33;
  719.        t.r23 := r21*c.r13+r22*c.r23+r23*c.r33;
  720.        t.r33 := r31*c.r13+r32*c.r23+r33*c.r33;
  721.        t.tz  := tx *c.r13+ty *c.r23+tz *c.r33+c.tz;
  722.  
  723.        copy(t);
  724. end; {ctm.multiply}
  725.  
  726. (*******************************************************************************
  727. *                                ctm.multiply_2                                *
  728. * here we multiply our ctm with another from the right : self * c -> self      *
  729. *******************************************************************************)
  730. procedure ctm.multiply_2;
  731. begin
  732.     r11 := a.r11*b.r11+a.r12*b.r21+a.r13*b.r31;
  733.     r21 := a.r21*b.r11+a.r22*b.r21+a.r23*b.r31;
  734.     r31 := a.r31*b.r11+a.r32*b.r21+a.r33*b.r31;
  735.     tx := a.tx *b.r11+a.ty *b.r21+a.tz *b.r31+b.tx;
  736.  
  737.     r12 := a.r11*b.r12+a.r12*b.r22+a.r13*b.r32;
  738.     r22 := a.r21*b.r12+a.r22*b.r22+a.r23*b.r32;
  739.     r32 := a.r31*b.r12+a.r32*b.r22+a.r33*b.r32;
  740.     ty := a.tx *b.r12+a.ty *b.r22+a.tz *b.r32+b.ty;
  741.  
  742.     r13 := a.r11*b.r13+a.r12*b.r23+a.r13*b.r33;
  743.     r23 := a.r21*b.r13+a.r22*b.r23+a.r23*b.r33;
  744.     r33 := a.r31*b.r13+a.r32*b.r23+a.r33*b.r33;
  745.     tz := a.tx *b.r13+a.ty *b.r23+a.tz *b.r33+b.tz;
  746. end; {ctm.multiply_2}
  747.  
  748.  
  749. (*******************************************************************************
  750. *                                ctm.inverse                                   *
  751. *******************************************************************************)
  752. procedure ctm.inverse;
  753. begin
  754.      runerror; { we have not implemented it yet .. }
  755. end; {ctm.inverse}
  756.  
  757. (******************************************************************************
  758. *                                    end.                                     *
  759. ******************************************************************************)
  760. end.
  761.